package com.baor.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baor.dao.*;
import com.baor.domain.*;
import com.baor.domain.conf.DistributionConf;
import com.baor.enums.FuncEnum;
import com.baor.service.ExamineService;
import com.baor.utils.AjaxResult;
import com.baor.utils.DateUtil;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.netflix.discovery.converters.Auto;
import org.apache.catalina.User;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ExamineServiceImpl implements ExamineService {

    @Autowired
    private ExamineDao examineDao;
    @Autowired
    private VipDao vipDao;
    @Autowired
    private DistributorDao distributorDao;
    @Autowired
    private OrderDao orderDao;
    @Autowired
    private DistributionConfDao distributionConfDao;
    @Autowired
    private DistributorServiceImpl distributorService;

    @Override
    public AjaxResult<?> list(Map<String,Object> param) {
        MPJLambdaWrapper<ExamineVo> mpj = new MPJLambdaWrapper<>();
        mpj.selectAll(ExamineVo.class)
                .selectAs(UserVo::getUserName, ExamineVo::getUserName)
                .selectAs(AdminVo::getAdminAccount, ExamineVo::getAdminId)
                .selectFunc(FuncEnum.CASE_EXAMINE, ExamineVo::getExamineStatus)
                .eq(ExamineVo::getSiteId, param.get("siteId"))
                .leftJoin(UserVo.class, UserVo::getUserId, ExamineVo::getUserId)
                .leftJoin(AdminVo.class, AdminVo::getAdminId, ExamineVo::getAdminId);
        if(param.get("info") != null){
            List<Integer> userId = getUserId(param);
            mpj.in(ExamineVo::getUserId, userId);
        }
        if(param.get("status") != null){
            mpj.eq(ExamineVo::getExamineStatus, param.get("status"));
        }
        if(param.get("startTime") != null && param.get("endTime") != null && !"".equals(param.get("startTime").toString())){
            mpj.gt(ExamineVo::getCreateTime, param.get("startTime"))
                    .lt(ExamineVo::getCreateTime, param.get("endTime"));
        }
        Map<String,Object> map = new HashMap<>();
        Page<ExamineVo> page = getPage(param);
        List<ExamineVo> list = examineDao.selectPage(page, mpj).getRecords();
        for(ExamineVo vo : list){
            vo.setSiteId(null);
//            int userId = Integer.parseInt(vipDao.selectById(vo.getUserId()).getUserSuperior());
            UserVo user = vipDao.selectById(vo.getSuperiorId());
            if(user != null)
                vo.setSuperiorId(user.getUserName());
            else
                vo.setSuperiorId("无");
            //查询消费次数和消费金额
            LambdaQueryWrapper<OrderVo> lqw = new LambdaQueryWrapper<>();
            lqw.eq(OrderVo::getOrderStatusId, "12")
                    .eq(OrderVo::getUserId, vo.getUserId());
            List<OrderVo> orderVos = orderDao.selectList(lqw);
            BigDecimal cost = new BigDecimal(0);
            for(OrderVo orderVo : orderVos){
                cost = cost.add(orderVo.getOrderRealAmount());
            }
            vo.setCostNum(orderVos.size());
            vo.setCost(cost);
        }
        map.put("list", list);
        map.put("pageCount", page.getPages());
        return AjaxResult.success(map);
    }

    @Override
    @Transactional
    public AjaxResult<?> approved(ExamineVo vo) {
        vo.setExamineStatus("2");
        examineDao.updateById(vo);
        ExamineVo examine = examineDao.selectById(vo.getExamineId());
        List<DistributorVo> lists = distributorDao.selectList(new LambdaQueryWrapper<DistributorVo>().eq(DistributorVo::getUserId, examine.getUserId()));
        if(lists.size() > 0){
            return AjaxResult.error("该用户已是分销商，请勿重复添加");
        }
        DistributorVo distributor = new DistributorVo();
        distributor.setDistributiorSuperior(examine.getSuperiorId());
        distributor.setCreateTime(DateUtil.now());
        distributor.setSiteId(examine.getSiteId());
        distributor.setUserId(examine.getUserId());
        Boolean flag = true;
        while(flag){
            String code = "NO" + DistributorServiceImpl.getNum();
            MPJLambdaWrapper<DistributorVo> mpj = new MPJLambdaWrapper<>();
            mpj.selectAll(DistributorVo.class)
                    .eq(DistributorVo::getDistributiorCode, code);
            List<DistributorVo> list = distributorDao.selectList(mpj);
            if(list.size() > 0){
                return AjaxResult.error("该编号已存在，请重新输入");
            }else {
                distributor.setDistributiorCode(code);
                flag = false;
            }
        }
        int row = distributorDao.insert(distributor);
        if (row > 0){
            UserVo user = vipDao.selectById(examine.getUserId());
            user.setUserSuperior(String.valueOf(examine.getSuperiorId()));
            vipDao.updateById(user);
            return AjaxResult.success();
        }else {
            return AjaxResult.error();
        }
    }

    @Override
    public AjaxResult<?> refuse(ExamineVo vo) {
        vo.setExamineStatus("1");
        int row = examineDao.updateById(vo);
        if (row > 0){
            return AjaxResult.success();
        }else {
            return AjaxResult.error();
        }
    }

    @Override
    public AjaxResult<?> details(ExamineVo vo) {
        MPJLambdaWrapper<ExamineVo> mpj = new MPJLambdaWrapper<>();
        mpj.selectAll(ExamineVo.class)
                .selectFunc(FuncEnum.CASE_EXAMINE, ExamineVo::getExamineStatus )
                .selectAs(AdminVo::getAdminAccount, ExamineVo::getAdminId)
                .eq(ExamineVo::getExamineId, vo.getExamineId())
                .leftJoin(AdminVo.class, AdminVo::getAdminId, ExamineVo::getAdminId);
        ExamineVo examine = examineDao.selectList(mpj).get(0);
        UserVo user = vipDao.selectById(examine.getUserId());
        examine.setImage(user.getUserImage());
        examine.setUserName(user.getUserName());
        DistributorVo id = distributorDao.selectById(examine.getSuperiorId());
        if(id != null) {
            UserVo user2 = vipDao.selectById(id.getUserId());
            examine.setSuperiorId(user2.getUserName());
        }else{
            examine.setSuperiorId("无");
        }
        return AjaxResult.success(examine);
    }

    @Override
    public AjaxResult<?> vipList(Map<String, Object> param) {
        Map<String,Object> res = new HashMap<>();
        List<DistributorVo> distributorVos = distributorDao.selectList(null);
        List<Map<String,Object>> list = new ArrayList<>();
        if(param.get("pageIndex") == null){
            param.put("pageIndex",0);
            param.put("pageSize",5);
        }else {
            int pageindex = Integer.valueOf(param.get("pageIndex").toString());
            int pageSize = Integer.valueOf(param.get("pageSize").toString());
            param.put("pageIndex",(pageindex-1)*pageSize);
        }
        List<UserVo> users = examineDao.selectUser(param);
        for(UserVo user : users){
            Map<String,Object> map = new HashMap<>();
            map.put("userId", user.getUserId());
            map.put("userName", user.getUserName());
            map.put("superior", user.getUserSuperior());
            for(DistributorVo distributorVo : distributorVos){
                if(user.getUserId() == Integer.parseInt(distributorVo.getUserId())){
                    map.put("isDistributor", "是");
                    break;
                }else{
                    map.put("isDistributor", "否");
                }
            }
            //查询消费次数和消费金额
            LambdaQueryWrapper<OrderVo> lqw = new LambdaQueryWrapper<>();
            lqw.eq(OrderVo::getOrderStatusId, "12")
                    .eq(OrderVo::getUserId, user.getUserId());
            List<OrderVo> orderVos = orderDao.selectList(lqw);
            BigDecimal cost = new BigDecimal(0);
            for(OrderVo orderVo : orderVos){
                cost = cost.add(orderVo.getOrderRealAmount());
            }
            map.put("costNum", orderVos.size());
            map.put("cost", cost);
            list.add(map);
        }
        res.put("list", list);
        res.put("pageCount", examineDao.pageCount(param));
        return AjaxResult.success(res);
    }

    @Override
    public AjaxResult<?> update(Map<String, Object> param) {
        UserVo user = new UserVo();
        user.setUserId(Integer.valueOf(param.get("userId").toString()) );
        user.setUserSuperior(param.get("superior").toString());
        int row = vipDao.updateById(user);
        if (row > 0){
            return AjaxResult.success();
        }else {
            return AjaxResult.error();
        }
    }


    @Override
    public AjaxResult<?> people(int userId) {
        int code = 0;
        UserVo user = vipDao.selectById(userId);
        LambdaQueryWrapper<OrderVo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(OrderVo::getOrderStatusId, "12")
                .eq(OrderVo::getUserId, user.getUserId());
        List<OrderVo> orderVos = orderDao.selectList(lqw);
        DistributorVo distributorVo = getDistributor(user);
        DistributionConf conf = distributionConfDao.selectOne(new LambdaQueryWrapper<DistributionConf>().eq(DistributionConf::getSiteId, user.getSiteId()));
        if(orderVos == null || orderVos.size() == 0 && conf.getConfDistributionCondition() == 0)
            code = distributorService.insert(distributorVo).getCode();
        if(conf.getConfMethod() == 1){
            if(conf.getConfDistributionCondition() == 0){
                code = distributorService.insert(distributorVo).getCode();
            } else if (conf.getConfDistributionCondition() == 1) {
                if(orderVos.size() >= 100) {
                    code = distributorService.insert(distributorVo).getCode();
                }
            } else if (conf.getConfDistributionCondition() == 2) {
                BigDecimal cost = new BigDecimal(0);
                for(OrderVo orderVo : orderVos){
                    cost = cost.add(orderVo.getOrderRealAmount());
                }
                if(cost.compareTo(new BigDecimal(10000)) >= 0) {
                    code = distributorService.insert(distributorVo).getCode();
                }
            }else {
                List<Integer> goodsIds = orderVos.stream().map(OrderVo::getGoodsId).map(Integer::parseInt).collect(Collectors.toList());
                if(goodsIds.contains(1) || goodsIds.contains(2)){
                    code = distributorService.insert(distributorVo).getCode();
                }
            }
        }
        if(code == 200)
            return AjaxResult.success();
        else
            return AjaxResult.error();
    }

    public DistributorVo getDistributor(UserVo user){
        DistributorVo distributorVo = new DistributorVo();
        distributorVo.setUserId(String.valueOf(user.getUserId()));
        distributorVo.setSiteId(user.getSiteId());
        distributorVo.setDistributionLevelId("2");
        int userId = vipDao.selectOne(new LambdaQueryWrapper<UserVo>().eq(UserVo::getUserId, user.getUserSuperior())).getUserId();
        int distributorId = distributorDao.selectOne(new LambdaQueryWrapper<DistributorVo>().eq(DistributorVo::getUserId, userId)).getDistributorId();
        distributorVo.setDistributorId(distributorId);
        return distributorVo;
    }


    private Page<ExamineVo> getPage(Map<String,Object> map){
        if ( map.get("pageIndex") == null || "".equals(map.get("pageIndex")) )
            map.put("pageIndex",1);
        if ( map.get("pageSize") == null || "".equals(map.get("pageSize")) )
            map.put("pageSize",10);
        Long pageIndex = Long.valueOf(map.get("pageIndex").toString());
        Long pageSize = Long.valueOf(map.get("pageSize").toString());
        Page<ExamineVo> page = new Page<>(pageIndex,pageSize);
        return page;
    }

    public List<Integer> getUserId(Map<String, Object> param) {
        MPJLambdaWrapper<UserVo> mpj = new MPJLambdaWrapper<>();
        mpj.select(UserVo::getUserId)
                .like(UserVo::getUserName, param.get("info").toString());
        return vipDao.selectList(mpj).stream().map(UserVo::getUserId).collect(Collectors.toList());
    }



}
